#include "GLTextureMixWindow.h"

GLTextureMixWindow::GLTextureMixWindow(QWidget* parent)
	: BaseOpenGLWindow(parent)
{
	this->setWindowTitle("纹理融合");
	QHBoxLayout* hLayout = new QHBoxLayout(this);
	QPushButton* btnRed = new QPushButton(this);
	btnRed->setText("融合系数增大（+）");
	QPushButton* btnGreen = new QPushButton(this);
	btnGreen->setText("融合系数减小（-）");
	QPushButton* btnFlipX = new QPushButton(this);
	btnFlipX->setText("x轴像素位置互换");
	hLayout->addWidget(btnRed);
	hLayout->addWidget(btnGreen);
	hLayout->addWidget(btnFlipX);
	hLayout->setAlignment(Qt::AlignTop);

	connect(btnRed, &QPushButton::clicked, [this]() {
		this->mixScale += 0.1f;
		if (this->mixScale >= 1.0f) this->mixScale = 1.0f;
		setMixScale(mixScale);
		});

	connect(btnGreen, &QPushButton::clicked, [=]() {
		this->mixScale -= 0.1f;
		if (this->mixScale < 0.0f) this->mixScale = 0.0f;
		setMixScale(mixScale);
		});

	connect(btnFlipX, &QPushButton::clicked, [=]() {
		flipToX();
		});

}
void GLTextureMixWindow::initializeGL() {
	this->initializeOpenGLFunctions();
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	float vertices[] = {
		//     ---- 位置 ----          - 纹理坐标 -
			 1.0f,  1.0f, 0.0f,   1.0f, 1.0f,   // 右上
			 1.0f, -1.0f, 0.0f,   1.0f, 0.0f,   // 右下
			-1.0f, -1.0f, 0.0f,   0.0f, 0.0f,   // 左下
			-1.0f,  1.0f, 0.0f,    0.0f, 1.0f    // 左上
	};
	//float vertices[] = {
	//	//     ---- 位置 ----          - 纹理坐标 -
	//		 1.0f,  1.0f, 0.0f,   4.0f, 4.0f,   // 右上
	//		 1.0f, -1.0f, 0.0f,   4.0f, 0.0f,   // 右下
	//		-1.0f, -1.0f, 0.0f,   0.0f, 0.0f,   // 左下
	//		-1.0f,  1.0f, 0.0f,    0.0f, 4.0f    // 左上
	//};
	unsigned int indices[] = {
	   0, 1, 3, // first triangle
	   1, 2, 3  // second triangle
	};
	//创建VAO、VBO、EBO
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1, &EBO);
	glBindVertexArray(VAO);

	////顶点数据存入缓冲区
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	////EBO
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

	////告知显卡顶点数据如何解析
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);

	////告知显卡纹理坐标如何解析
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);

	stbi_set_flip_vertically_on_load(true);
	texture = buildTexture("E:/tony/demo/visualstudio_workspace/QtForOpenCV4Tool/QtForOpenCV4Tool/bin/images/flowers.jpeg",
		GL_RGB);
	texture1 = buildTexture("E:/tony/demo/visualstudio_workspace/QtForOpenCV4Tool/QtForOpenCV4Tool/bin/images/similing_face.png",
		GL_RGBA);

	//小程序
	programId = buildAttachShaderAndReturnProgramId(":/QtForOpenCV4Tool/shader/texture_mix.vert",
		":/QtForOpenCV4Tool/shader/texture_mix.frag");
}
GLuint GLTextureMixWindow::buildTexture(QString textureFileName, GLint imageColorType) {
	GLuint mTexture;
	////创建纹理
	glGenTextures(1, &mTexture);
	glBindTexture(GL_TEXTURE_2D, mTexture);
	//设置纹理环绕方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	//设置纹理过滤方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	//生成纹理
	int width, height, mChannels;
	//QString path = getTexturePath(textureFileName);
	//qDebug() << path.toStdString().c_str();
	unsigned char* data = stbi_load(textureFileName.toStdString().c_str(), &width, &height, &mChannels, 0);
	if (data) {
		qDebug() << "图片加载成功,width=" << width << ",height=" << height;
		glTexImage2D(GL_TEXTURE_2D, 0, imageColorType, width, height, 0, imageColorType, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else {
		qDebug() << "图像数据加载失败";
	}
	stbi_image_free(data);

	return mTexture;
}
void GLTextureMixWindow::resizeGL(int w, int h) {
	glViewport(0, 0, w, h);
}
void GLTextureMixWindow::paintGL() {
	glBindVertexArray(VAO);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, texture);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, texture1);
	glUseProgram(programId);
	glUniform1f(glGetUniformLocation(programId, "flip_x"), flip_x);
	glUniform1f(glGetUniformLocation(programId, "maxScale"), mixScale);
	//指定纹理单元编号
	GLint ourTextureLocation = glGetUniformLocation(programId, "ourTexture1");
	glUniform1i(ourTextureLocation, 0);
	GLint ourTexture1Location = glGetUniformLocation(programId, "ourTexture2");
	glUniform1i(ourTexture1Location, 1);

	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
void GLTextureMixWindow::setMixScale(float mix) {
	this->mixScale = mix;
	update();
}
void GLTextureMixWindow::flipToX() {
	this->flip_x = -this->flip_x;
	update();
}
GLTextureMixWindow::~GLTextureMixWindow()
{
}
